<!-- 查询 agent -->
{{ $agentSQL := "* FROM agent WHERE id=? and status=1 order by status desc, sortNo desc" }}

{{ if eq .userType 1}}
  {{ $agentSQL ="* FROM agent WHERE id=? order by sortNo desc" }}
{{end}}

{{ $agent := selectOne "agent" $agentSQL .agentID }}
<!DOCTYPE html>
<html lang="{{locale}}">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" document="IE=edge">
    <meta name="viewport" document="width=device-width, initial-scale=1">
    <title>{{$agent.Name}} - MINRAG</title>
    <link rel="stylesheet" href="{{basePath}}css/agent.css" />

</head>
<script>
    const basePath="{{basePath}}";
    const locale="{{locale}}";
</script>

<body>
    <div class="chat-container">
        <!-- 聊天对话框 -->
        <div class="chat-panel">
            <div class="chat-header">{{$agent.Name}}</div>
            <div class="chat-messages">
                <div class="message ai-message"><p>{{$agent.Welcome}}</p></div>
            </div>
            <div class="footer">
                <div class="input-container">
                    <textarea id="input-box" placeholder='{{T "Send a message to minRAG"}}'></textarea>
                    <button id="send-button">{{T "Send"}}</button>
                </div>
                <div class="copyright">内容由 <a href="https://gitee.com/minrag/minrag" target="_blank">minRAG</a> 调用 AI 大模型生成，请仔细甄别</div>
            </div>
        </div>
    </div>
</body>
<script src="{{basePath}}js/jquery-3.7.1.min.js"></script>
<script src="{{basePath}}js/marked.min.js"></script>
<script>
function generateStringID() {
    let randomNum="";
    for (i = 0; i < 9; i++) {
        randomNum=randomNum+""+Math.floor(Math.random()*10)
    }

    // 获取当前时间的纳秒级时间戳
    const now = new Date();
    const year = now.getFullYear();
    const month = String(now.getMonth() + 1).padStart(2, '0');
    const day = String(now.getDate()).padStart(2, '0');
    const hour = String(now.getHours()).padStart(2, '0');
    const minute = String(now.getMinutes()).padStart(2, '0');
    const second = String(now.getSeconds()).padStart(2, '0');
    const milliseconds = String(now.getMilliseconds()).padStart(3, '0');

    // 获取更高精度的时间（纳秒级）
    const performanceNow = performance.now();
    const microseconds = String(Math.floor((performanceNow % 1) * 1000)).padStart(3, '0');
    const nanoseconds = String(Math.floor((performanceNow % 1e-3) * 1e6)).padStart(3, '0');

    // 拼接时间字符串
    const pk = `${year}${month}${day}${hour}${minute}${second}${milliseconds}${microseconds}${nanoseconds}`;

    // 拼接最终的32位字符串
    const result = `${pk}${randomNum}`;
    return result;
}
var roomID=generateStringID();

var oldRoomID=localStorage.getItem("roomID");
if(!!oldRoomID){
    roomID=oldRoomID;
}else{
    localStorage.setItem("roomID", roomID);
}

$(document).ready(function() {
    $('#send-button').click(function() {
        sendMessage();
    });
    $('#input-box').keydown(function(event) {
        if (event.key === 'Enter') {
            sendMessage();
           // 阻止默认行为（避免换行或提交表单）
           event.preventDefault();
        }
    });
});

async function fetchSSE(aiMessageId,messageText) {
    let textMarkdown="";
    let thinkMarkdown="";
    let isThinking=false;
    let isReasoning=false;
    try {
        const response = await fetch('{{basePath}}v1/chat/completions', {
            method: 'POST',
            headers: {
                'Authorization': 'Bearer {{.agentID}}',
                'Accept': 'text/event-stream',
                'Cache-Control':'no-cache',
                'Connection':'keep-alive',
            },
            body:JSON.stringify({
                "messages": [{"role":"user","content":messageText}],
                "user":roomID,
            }),
        });

        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }

        const reader = response.body.getReader();
        const decoder = new TextDecoder('utf-8');

        while (true) {
            const { done, value } = await reader.read();
            if (done) {
                console.log('Stream complete');
                break;
            }

            const chunk = decoder.decode(value, { stream: true });
            const blocks=chunk.split("\n\n\n\n");
            for (let i = 0; i < blocks.length; i++) {
                const block=blocks[i];
                const lines=block.split("\n\n");
                for(const line of lines){
                    let prefix=""
                    let data = line
                    //console.log(data)
                    if (data.startsWith('\n')) {
                        prefix='\n'
                        data = line.substring(1);
                    }
                    if (data.startsWith('data: ')) {
                        data = line.substring(6);
                    }
                    if(data=="[DONE]"){
                        data=""
                    }
                    try {
                        let content=""
                        let reasoningContent=""
                        if(data!=""){
                            const openaiResponse = JSON.parse(data);
                            content=openaiResponse.choices[0].delta.content;
                            const type=openaiResponse.choices[0].delta.type
                            reasoningContent=openaiResponse.choices[0].delta.reasoning_content;
                           
                            if(!!reasoningContent){// reasoning_content 有值
                                content=""
                                isThinking=true;
                                isReasoning=true;
                            }else if (!!type){//兼容 type:"thinking" 的模式
                                if (type.indexOf("think")>=0){
                                    isThinking=true;
                                    reasoningContent=content;
                                }else{
                                    isThinking=false;
                                }
                            }else if(content=="<think>"){// 兼容think标签的方式
                                content=""
                                reasoningContent="";
                                isThinking=true;
                            }else if(content=="</think>"){
                                content=""
                                reasoningContent="";
                                isThinking=false;
                            }
                        }

                        if(!!!content){
                            content=""
                        }
                        if(!!!reasoningContent){
                            reasoningContent=""
                        }

                        if (isThinking&&isReasoning&&content!=""){  //isReasoning模式,属于思维链,但是content有值,思维链已经结束
                            isThinking=false
                        }

                        if (isThinking&&content!=""&&reasoningContent==""){// 思维链模式,但是content有值,reasoningContent无值
                            reasoningContent=content;
                        }
                        
                        if (isThinking){//思维链
                            thinkMarkdown=thinkMarkdown+prefix+reasoningContent;
                        }else{
                            textMarkdown=textMarkdown+prefix+content;
                        }
                    }catch(err) {
                            textMarkdown=textMarkdown+prefix+data;
                    }
                    
                }
                if(i>0){
                    if (!!reasoningContent){//思维链
                        thinkMarkdown=thinkMarkdown+'\n\n';
                    }else{
                        textMarkdown=textMarkdown+'\n\n';
                    }
                }
                
            }
            if (isThinking){//思维链
                let thinkDataHtml = marked.parse(thinkMarkdown);
                document.getElementById(aiMessageId+"_think").innerHTML=thinkDataHtml
            }else{
                $("#"+aiMessageId+"_markdown").val(textMarkdown)
                let textDataHtml = marked.parse(textMarkdown);
                document.getElementById(aiMessageId).innerHTML=textDataHtml
            }

        }
            
        
    } catch (error) {
        console.error('Fetch stream failed:', error);
    }
}

function sendMessage() {
    const messageText = $('#input-box').val().trim();
    if (!!!messageText) {
        return
    }
    const userMessage = $('<div class="message user-message"></div>').text(messageText);
    $('.chat-messages').append(userMessage);
    $('#input-box').val('');

    const aiMessageId=new Date().getTime()+"_aiMessage"
    const aiMessage = $('<div class="message ai-message"><div class="ai-message-think" id="'+aiMessageId+'_think"></div><div id="'+aiMessageId+'"></div></div><input type="hidden" id="'+aiMessageId+'_markdown">');
    $('.chat-messages').append(aiMessage);
    $('.chat-messages').scrollTop($('.chat-messages')[0].scrollHeight);

    fetchSSE(aiMessageId,messageText)
}
</script>

</html>